package com.jl15988.simpletools.appcore.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jl15988.simpletools.appcore.constant.AppConstant;
import com.jl15988.simpletools.appcore.dto.AppDTO;
import com.jl15988.simpletools.appcore.dto.AppQueryDTO;
import com.jl15988.simpletools.appcore.dto.AppRequestDTO;
import com.jl15988.simpletools.appcore.dto.CategoryDTO;
import com.jl15988.simpletools.appcore.entity.App;
import com.jl15988.simpletools.appcore.entity.Screenshot;
import com.jl15988.simpletools.appcore.mapper.AppCategoryMapper;
import com.jl15988.simpletools.appcore.mapper.AppMapper;
import com.jl15988.simpletools.appcore.mapper.DownloadLogMapper;
import com.jl15988.simpletools.appcore.mapper.ReviewMapper;
import com.jl15988.simpletools.appcore.mapper.ScreenshotMapper;
import com.jl15988.simpletools.appcore.service.AppService;
import com.jl15988.simpletools.appcore.service.CategoryService;
import com.jl15988.simpletools.appcore.service.FileStorageService;
import com.jl15988.simpletools.common.exception.BusinessException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 应用服务实现类
 *
 * @author jl15988
 */
@Service
public class AppServiceImpl extends ServiceImpl<AppMapper, App> implements AppService {

    @Autowired
    private AppMapper appMapper;

    @Autowired
    private AppCategoryMapper appCategoryMapper;

    @Autowired
    private ScreenshotMapper screenshotMapper;

    @Autowired
    private ReviewMapper reviewMapper;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private FileStorageService fileStorageService;

    @Autowired
    private DownloadLogMapper downloadLogMapper;

    @Override
    public IPage<AppDTO> getAppPage(AppQueryDTO query) {
        Page<App> page = new Page<>(query.getPageNum(), query.getPageSize());
        IPage<App> appPage = appMapper.selectAppPage(page, query);
        
        // 转换为DTO
        return appPage.convert(app -> {
            AppDTO dto = convertToDTO(app);
            // 获取分类信息
            dto.setCategories(categoryService.getCategoriesByAppId(app.getId()));
            // 获取截图信息
            dto.setScreenshots(getScreenshotsByAppId(app.getId()));
            return dto;
        });
    }

    @Override
    public AppDTO getAppDetail(Long id) {
        App app = appMapper.selectById(id);
        if (app == null) {
            throw new BusinessException("应用不存在");
        }
        
        AppDTO dto = convertToDTO(app);
        // 获取分类信息
        dto.setCategories(categoryService.getCategoriesByAppId(id));
        // 获取截图信息
        dto.setScreenshots(getScreenshotsByAppId(id));
        
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createApp(AppRequestDTO request, MultipartFile icon, MultipartFile appPackage, 
                         MultipartFile[] screenshots, Long userId, String username) {
        // 检查应用名称是否已存在
        LambdaQueryWrapper<App> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(App::getName, request.getName());
        if (appMapper.selectCount(wrapper) > 0) {
            throw new BusinessException("应用名称已存在");
        }
        
        // 检查应用包名是否已存在
        wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(App::getPackageName, request.getPackageName());
        if (appMapper.selectCount(wrapper) > 0) {
            throw new BusinessException("应用包名已存在");
        }
        
        // 创建应用
        App app = new App();
        BeanUtils.copyProperties(request, app);
        app.setStatus(AppConstant.STATUS_PENDING); // 默认待审核
        app.setDownloads(0L); // 初始下载次数为0
        app.setDeveloperId(userId);
        app.setDeveloperName(username);
        app.setCreatedAt(LocalDateTime.now());
        app.setUpdatedAt(LocalDateTime.now());
        
        appMapper.insert(app);
        Long appId = app.getId();
        
        // 处理图标
        if (icon != null && !icon.isEmpty()) {
            String iconPath = fileStorageService.storeIcon(icon, appId);
            app.setIcon(iconPath);
            appMapper.updateById(app);
        }
        
        // 处理应用包
        if (appPackage != null && !appPackage.isEmpty()) {
            String packagePath = fileStorageService.storePackage(appPackage, appId);
            app.setPackagePath(packagePath);
            app.setSize(appPackage.getSize()); // 设置应用大小
            appMapper.updateById(app);
        }
        
        // 处理分类关联
        if (request.getCategoryIds() != null && !request.getCategoryIds().isEmpty()) {
            appCategoryMapper.batchInsert(appId, request.getCategoryIds());
        }
        
        // 处理截图
        if (screenshots != null && screenshots.length > 0) {
            for (int i = 0; i < screenshots.length; i++) {
                MultipartFile screenshotFile = screenshots[i];
                if (screenshotFile != null && !screenshotFile.isEmpty()) {
                    String screenshotPath = fileStorageService.storeScreenshot(screenshotFile, appId, i);
                    
                    Screenshot screenshot = new Screenshot();
                    screenshot.setAppId(appId);
                    screenshot.setPath(screenshotPath);
                    screenshot.setSortOrder(i);
                    screenshot.setCreatedAt(LocalDateTime.now());
                    
                    screenshotMapper.insert(screenshot);
                }
            }
        }
        
        return appId;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateApp(AppRequestDTO request, MultipartFile icon, MultipartFile appPackage, 
                            MultipartFile[] screenshots, Long userId) {
        App app = appMapper.selectById(request.getId());
        if (app == null) {
            throw new BusinessException("应用不存在");
        }
        
        // 检查是否是开发者或管理员
        if (!app.getDeveloperId().equals(userId)) {
            throw new BusinessException("只有应用开发者才能更新应用");
        }
        
        // 检查应用名称是否已存在（排除自身）
        LambdaQueryWrapper<App> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(App::getName, request.getName())
                .ne(App::getId, request.getId());
        if (appMapper.selectCount(wrapper) > 0) {
            throw new BusinessException("应用名称已存在");
        }
        
        // 检查应用包名是否已存在（排除自身）
        wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(App::getPackageName, request.getPackageName())
                .ne(App::getId, request.getId());
        if (appMapper.selectCount(wrapper) > 0) {
            throw new BusinessException("应用包名已存在");
        }
        
        // 更新应用基本信息
        BeanUtils.copyProperties(request, app);
        app.setStatus(AppConstant.STATUS_PENDING); // 更新后重新审核
        app.setUpdatedAt(LocalDateTime.now());
        
        // 处理图标
        if (icon != null && !icon.isEmpty()) {
            // 删除旧图标
            if (app.getIcon() != null && !app.getIcon().isEmpty()) {
                fileStorageService.deleteFile(app.getIcon());
            }
            String iconPath = fileStorageService.storeIcon(icon, app.getId());
            app.setIcon(iconPath);
        }
        
        // 处理应用包
        if (appPackage != null && !appPackage.isEmpty()) {
            // 删除旧应用包
            if (app.getPackagePath() != null && !app.getPackagePath().isEmpty()) {
                fileStorageService.deleteFile(app.getPackagePath());
            }
            String packagePath = fileStorageService.storePackage(appPackage, app.getId());
            app.setPackagePath(packagePath);
            app.setSize(appPackage.getSize()); // 更新应用大小
        }
        
        appMapper.updateById(app);
        
        // 更新分类关联
        if (request.getCategoryIds() != null && !request.getCategoryIds().isEmpty()) {
            // 删除旧关联
            appCategoryMapper.deleteByAppId(app.getId());
            // 添加新关联
            appCategoryMapper.batchInsert(app.getId(), request.getCategoryIds());
        }
        
        // 处理截图
        if (screenshots != null && screenshots.length > 0) {
            // 删除旧截图
            List<Screenshot> oldScreenshots = getScreenshotEntitiesByAppId(app.getId());
            for (Screenshot oldScreenshot : oldScreenshots) {
                fileStorageService.deleteFile(oldScreenshot.getPath());
            }
            screenshotMapper.deleteByAppId(app.getId());
            
            // 添加新截图
            for (int i = 0; i < screenshots.length; i++) {
                MultipartFile screenshotFile = screenshots[i];
                if (screenshotFile != null && !screenshotFile.isEmpty()) {
                    String screenshotPath = fileStorageService.storeScreenshot(screenshotFile, app.getId(), i);
                    
                    Screenshot screenshot = new Screenshot();
                    screenshot.setAppId(app.getId());
                    screenshot.setPath(screenshotPath);
                    screenshot.setSortOrder(i);
                    screenshot.setCreatedAt(LocalDateTime.now());
                    
                    screenshotMapper.insert(screenshot);
                }
            }
        }
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteApp(Long id, Long userId) {
        App app = appMapper.selectById(id);
        if (app == null) {
            throw new BusinessException("应用不存在");
        }
        
        // 检查是否是开发者或管理员
        if (!app.getDeveloperId().equals(userId)) {
            throw new BusinessException("只有应用开发者才能删除应用");
        }
        
        // 删除应用文件
        fileStorageService.deleteAppFiles(id);
        
        // 删除分类关联
        appCategoryMapper.deleteByAppId(id);
        
        // 删除截图
        screenshotMapper.deleteByAppId(id);
        
        // 删除评论
        reviewMapper.deleteByAppId(id);
        
        // 删除应用
        return appMapper.deleteById(id) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAppStatus(Long id, Integer status) {
        App app = appMapper.selectById(id);
        if (app == null) {
            throw new BusinessException("应用不存在");
        }
        
        // 检查状态是否有效
        if (status != AppConstant.STATUS_PENDING && 
            status != AppConstant.STATUS_PUBLISHED && 
            status != AppConstant.STATUS_OFFLINE) {
            throw new BusinessException("无效的应用状态");
        }
        
        app.setStatus(status);
        app.setUpdatedAt(LocalDateTime.now());
        
        return appMapper.updateById(app) > 0;
    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public String downloadApp(Long id, Long userId, HttpServletRequest request) {
//        App app = appMapper.selectById(id);
//        if (app == null) {
//            throw new BusinessException("应用不存在");
//        }
//
//        // 检查应用状态
//        if (app.getStatus() != AppConstant.STATUS_PUBLISHED) {
//            throw new BusinessException("应用未发布，无法下载");
//        }
//
//        // 检查应用包是否存在
//        if (app.getFileUrl() == null || app.getFileUrl().isEmpty()) {
//            throw new BusinessException("应用包不存在");
//        }
//
//        // 增加下载次数
//        appMapper.incrementDownloads(id);
//
//        // 记录下载日志
//        DownloadLog downloadLog = new DownloadLog();
//        downloadLog.setAppId(id);
//        downloadLog.setUserId(userId);
//        downloadLog.setIp(getClientIp(request));
//        downloadLog.setUserAgent(request.getHeader("User-Agent"));
//        downloadLog.setDownloadDate(LocalDateTime.now());
//        downloadLogMapper.insert(downloadLog);
//
//        return app.getFileUrl();
//    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submitToAudit(Long id, Long userId) {
        App app = appMapper.selectById(id);
        if (app == null) {
            throw new BusinessException("应用不存在");
        }
        
        // 检查是否是开发者
        if (!app.getDeveloperId().equals(userId)) {
            throw new BusinessException("只有应用开发者才能提交审核");
        }
        
        // 检查应用状态
        if (app.getStatus() == AppConstant.STATUS_PUBLISHED) {
            throw new BusinessException("应用已发布，无需提交审核");
        }
        
        // 检查必要信息是否完整
        if (app.getIcon() == null || app.getIcon().isEmpty()) {
            throw new BusinessException("应用图标不能为空");
        }
        
        if (app.getPackagePath() == null || app.getPackagePath().isEmpty()) {
            throw new BusinessException("应用包不能为空");
        }
        
        // 检查是否有截图
        List<Screenshot> screenshots = getScreenshotEntitiesByAppId(app.getId());
        if (screenshots.isEmpty()) {
            throw new BusinessException("应用截图不能为空");
        }
        
        // 检查是否有分类
        List<CategoryDTO> categories = categoryService.getCategoriesByAppId(app.getId());
        if (categories.isEmpty()) {
            throw new BusinessException("应用分类不能为空");
        }
        
        // 更新应用状态为待审核
        app.setStatus(AppConstant.STATUS_PENDING);
        app.setUpdatedAt(LocalDateTime.now());
        
        return appMapper.updateById(app) > 0;
    }

    /**
     * 将实体转换为DTO
     *
     * @param app 应用实体
     * @return 应用DTO
     */
    private AppDTO convertToDTO(App app) {
        AppDTO dto = new AppDTO();
        BeanUtils.copyProperties(app, dto);
        return dto;
    }

    /**
     * 获取应用截图路径列表
     *
     * @param appId 应用ID
     * @return 截图路径列表
     */
    private List<String> getScreenshotsByAppId(Long appId) {
        List<Screenshot> screenshots = getScreenshotEntitiesByAppId(appId);
        return screenshots.stream()
                .map(Screenshot::getPath)
                .collect(Collectors.toList());
    }

    /**
     * 获取应用截图实体列表
     *
     * @param appId 应用ID
     * @return 截图实体列表
     */
    private List<Screenshot> getScreenshotEntitiesByAppId(Long appId) {
        LambdaQueryWrapper<Screenshot> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Screenshot::getAppId, appId)
                .orderByAsc(Screenshot::getSortOrder);
        return screenshotMapper.selectList(wrapper);
    }

    /**
     * 获取客户端IP地址
     *
     * @param request HTTP请求
     * @return IP地址
     */
    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
} 